package my.mall.common.util

import org.apache.poi.ss.usermodel.BorderStyle
import org.apache.poi.ss.usermodel.FillPatternType
import org.apache.poi.ss.usermodel.HorizontalAlignment
import org.apache.poi.ss.usermodel.IndexedColors
import org.apache.poi.xssf.usermodel.XSSFRichTextString
import org.apache.poi.xssf.usermodel.XSSFWorkbook
import java.io.OutputStream
import java.time.LocalDate
import java.time.LocalDateTime
import java.util.*

object ExcelUtils {

    inline fun <reified T> exportExcel2007(title: String?, headers: Array<Array<String>>, dataset: Collection<T>, out: OutputStream) {
        // 声明一个工作薄
        val workbook = XSSFWorkbook()
        // 生成一个表格
        val sheet = workbook.createSheet(title)
        // 设置表格默认列宽度为15个字节
        sheet.defaultColumnWidth = 20
        // 生成表头样式
        val headerStyle = workbook.createCellStyle()
        // 设置这些样式
        headerStyle.fillForegroundColor = IndexedColors.GREY_50_PERCENT.getIndex()
        headerStyle.fillPattern = FillPatternType.SOLID_FOREGROUND
        headerStyle.borderBottom = BorderStyle.THIN
        headerStyle.borderLeft = BorderStyle.THIN
        headerStyle.borderRight = BorderStyle.THIN
        headerStyle.borderTop = BorderStyle.THIN
        headerStyle.alignment = HorizontalAlignment.CENTER
        // 生成一个字体
        val headerFont = workbook.createFont()
        headerFont.fontName = "宋体"
        headerFont.color = IndexedColors.WHITE.getIndex()
        headerFont.fontHeightInPoints = 11.toShort()
        // 把字体应用到当前的样式
        headerStyle.setFont(headerFont)
        // 产生表格标题行
        val headerRow = sheet.createRow(0)
        for (i in headers.indices) {
            val header = headers[i]
            val cell = headerRow.createCell(i)
            cell.cellStyle = headerStyle
            cell.setCellValue(XSSFRichTextString(header[0]))
        }

        // 生成并设置表格样式
        val bodyStyle = workbook.createCellStyle()
        bodyStyle.fillForegroundColor = IndexedColors.WHITE.getIndex()
        bodyStyle.fillPattern = FillPatternType.SOLID_FOREGROUND
        bodyStyle.borderBottom = BorderStyle.THIN
        bodyStyle.borderLeft = BorderStyle.THIN
        bodyStyle.borderRight = BorderStyle.THIN
        bodyStyle.borderTop = BorderStyle.THIN
        bodyStyle.alignment = HorizontalAlignment.CENTER

        // 遍历集合数据，产生数据行
        val it = dataset.iterator()
        val clazz = T::class.java
        var index = 0
        while (it.hasNext()) {
            val row = sheet.createRow(++index)
            val t = it.next()
            // 利用反射，根据JavaBean属性的先后顺序，动态调用getXxx()方法得到属性值
            for (i in headers.indices) {
                val cell = row.createCell(i)
                val column = headers[i][1]
                cell.cellStyle = bodyStyle
                val getMethodName = "get" + column.substring(0, 1).uppercase(Locale.getDefault()) + column.substring(1)
                val getMethod = clazz.getMethod(getMethodName)
                val value = getMethod.invoke(t)
                var textValue: String? = null
                if (value is Boolean) {
                    textValue = "是"
                    if (!value) {
                        textValue = "否"
                    }
                } else if (value is LocalDate) {
                    textValue = DateUtils.formatLocalDate(value)
                } else if (value is LocalDateTime) {
                    textValue = DateUtils.formatLocalDateTime(value)
                } else {
                    if (value != null) {
                        textValue = value.toString()
                    }
                }
                if (textValue != null) {
                    cell.setCellValue(textValue)
                }
            }
        }
        workbook.write(out)
    }
}
